package pres.wchen.bussiness.cor.svnkit;

import com.google.gson.Gson;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.*;
import pres.wchen.bussiness.cor.util.DateUtils;
import sun.rmi.runtime.Log;

import java.io.File;
import java.util.*;

/**
 * @作者： wchen
 * @描述：
 * @创建时间： 2018/2/19 8:25
 * @版本：Copyright 2018, Inc. All Rights Reserved.
 * @修改信息：
 */
public class SvnkitManager {
    public static final String ADMIN_URL = "svn://123.206.176.29/v12/发布包/admin";
    public static final String CLIENT_URL = "svn://123.206.176.29/v12/发布包/client";
    public static final String SERVICE_SYS_URL = "svn://123.206.176.29/v12/发布包/weishier-service-sys";
    public static final String SERVICE_MALL_URL = "svn://123.206.176.29/v12/发布包/weishier-service-mall";
    public static final String SERVICE_WEBSITE_URL = "svn://123.206.176.29/v12/发布包/weishier-service-website";
    public static final String TIMER_URL = "svn://123.206.176.29/v12/发布包/weishier-timer-core";


    private static SVNClientManager svnClientManager;
    private static final Gson gson = new Gson();
    private static SVNRepository repository;
    private SvnkitManager(){
    }

    public static SVNClientManager newInstance(){
        if(svnClientManager == null){
//            DAVRepositoryFactory.setup();
            SVNRepositoryFactoryImpl.setup();
            //2.使用默认选项
            ISVNOptions isvnOptions = SVNWCUtil.createDefaultOptions(true);
            //3.初始化权限
            String username = "chenwu";
            String password = "123456";
            char[] pwd = password.toCharArray();
            ISVNAuthenticationManager isvnAuthenticationManager = SVNWCUtil.createDefaultAuthenticationManager(username,pwd);
            //4.创建SVNClientManager的实例
            svnClientManager = SVNClientManager.newInstance(isvnOptions,isvnAuthenticationManager);

        }
        return svnClientManager;
    }

    public static void main(String[] args) throws Exception{
        //1.根据访问协议初始化工厂
        DAVRepositoryFactory.setup();
        //2.使用默认选项
        ISVNOptions isvnOptions = SVNWCUtil.createDefaultOptions(true);
        //3.初始化权限
        String username = "chenwu";
        String password = "123456";
        char[] pwd = password.toCharArray();
        ISVNAuthenticationManager isvnAuthenticationManager = SVNWCUtil.createDefaultAuthenticationManager(username,pwd);
        //4.创建SVNClientManager的实例
        svnClientManager = SVNClientManager.newInstance(isvnOptions,isvnAuthenticationManager);

//        SVNURL requestUrl = SVNURL.parseURIEncoded( "svn://123.206.176.29/v12/发布包/weishier-timer-core");
        repository = SVNRepositoryFactory.create(
                SVNURL.parseURIEncoded( "svn://123.206.176.29/v12/发布包/weishier-timer-core"),
                null );
        repository.setAuthenticationManager(isvnAuthenticationManager);
        List<Map> resultList = doSvnHistory(0, -1, "");
        for(Map resultMap : resultList){
            System.out.println(resultMap.toString());
        }
        //=========================================demo start=======================================

//        String repositoryPath = "E:\\编程\\WEB容器\\apache-tomcat-8.0.47\\webapps\\weishier-timer-core";
////
//        SVNInfo svnInfo = svnClientManager.getWCClient().doInfo(
//                new File(repositoryPath), SVNRevision.create(-1));
//        System.out.println("执行info操作成功，操作结果：" + gson.toJson(svnInfo));
//
//
//        SVNLogClient svnLogClient = svnClientManager.getLogClient();
////        SVNURL url, String[] paths, SVNRevision pegRevision, SVNRevision startRevision, SVNRevision endRevision, boolean stopOnCopy, boolean discoverChangedPaths, long limit, ISVNLogEntryHandler handler
//
//        String svnUrl = "svn://123.206.176.29/v12/发布包/weishier-timer-core";
//        svnLogClient.doLog(svnUrl, null, SVNRevision.HEAD, SVNRevision.HEAD, SVNRevision.HEAD, true, false, null, null);



        //1.导入-import
//      doImport();
        //2.检出-checkout
//        doCheckout();
        //3.创建目录-mkdir
//      doMkDir();
        //4.提交-commit
//      doCommit();
        //5.更新-update
//        doUpdate(repositoryPath);
        //6.切换分支-switch
        //7.添加-add，在commit中有体现，提交前，没有加入版本控制的文件需要加入版本控制
        //8.锁定-lock
//        doLock();
        //9.删除-delete
//        doDelete();
        //10.拷贝-copy
//        doCopy();
        //11.状态-status
//        doStatus();
        //12.信息-info
//        doInfo();
    }


    /**
     *  @描述: 获取svn历史记录
     *  @参数： [startRevision, endRevision]
     *  @返回值： java.util.List<java.util.Map>
     *  @创建人: wchen
     *  @创建时间: 2018/2/20
     *  @修改人和其它信息:
     */
    public static List<Map> doSvnHistory(long startRevision, long endRevision, String svnUrl) {
        SVNRepository repository = null;
        //        if(repository == null){
            try {
                String username = "chenwu";
                String password = "123456";
                repository = SVNRepositoryFactory.create( SVNURL.parseURIEncoded( svnUrl), null );
                ISVNAuthenticationManager isvnAuthenticationManager =
                        SVNWCUtil.createDefaultAuthenticationManager(username,password.toCharArray());
                repository.setAuthenticationManager(isvnAuthenticationManager);
            }catch (Exception e){
                System.out.println("地址解析错误：" );
                e.printStackTrace();
            }
//        }

        Collection<SVNLogEntry> logEntries = new LinkedList<>();
        try {
            Long latestRevision = repository.getLatestRevision();
            System.out.println("最新的版本号：" + latestRevision);
            //布尔变量changedPath为true时，收集的历史记录里包括受影响的文件及目录信息，
            // 受影响的文件及目录信息可以使用SVNLogEntry.getChangedPaths()方法进行获取。
            // 布尔变量strictNode为true时，返回的历史记录包括复制操作的记录信息。
            repository.log(new String[] { "/" }, logEntries, startRevision,
                    endRevision, true, true);
        } catch (SVNException svne) {
            System.out.println("获取资源库历史记录时出错: " + svne.getMessage());
        }
        List<Map> resultList = new ArrayList<>();
        for (SVNLogEntry logEntry : logEntries) {
            Map resultMap = new HashMap();
            resultMap.put("revision", logEntry.getRevision());
            resultMap.put("author", logEntry.getAuthor());
            resultMap.put("dateTime", DateUtils.formatDateTime(logEntry.getDate(), "yyyy-mm-dd hh:mm:ss"));
            resultMap.put("message", logEntry.getMessage());
            resultList.add(resultMap);
//            System.out.println("---------------------------------------------");
//            // 获取修改版本号
//            System.out.println("修订版本号: " + logEntry.getRevision());
//            // 获取提交者
//            System.out.println("提交者: " + logEntry.getAuthor());
//            // 获取提交时间
//            System.out.println("日期: " + logEntry.getDate());
//            // 获取注释信息
//            System.out.println("注释信息: " + logEntry.getMessage());
//            if (logEntry.getChangedPaths().size() > 0) {
//                System.out.println();
//                System.out.println("受影响的文件、目录:");
//                for (Map.Entry<String, SVNLogEntryPath> entry : logEntry
//                        .getChangedPaths().entrySet()) {
//                    System.out.println(entry.getValue());
//                }
//            }
        }
        return resultList;
    }

    /*
     * 导入-import
     * @throws SVNException
     */
    private static void doImport() throws SVNException{
        SVNProperties svnProperties = new SVNProperties();
        boolean useGlobalIgnores = true;
        boolean ignoreUnknownNodeTypes = true;
        SVNCommitInfo svnCommitInfo = svnClientManager.getCommitClient().doImport(new File("E:\\svnWorkspace\\commonProject"),SVNURL.parseURIEncoded("https://wlyfree-PC:8443/svn/testRepository/trunk"),"初始化导入",svnProperties,useGlobalIgnores,ignoreUnknownNodeTypes,SVNDepth.INFINITY);
        System.out.println("执行import操作成功，导入结果：" + gson.toJson(svnCommitInfo));
    }

    /**
     * 检出-checkout
     * 参数：
     *  仓库地址
     *  本地Working Copy地址
     *  Peg Revision
     *  Revision
     *  检出深度，一般递归检出
     *  是否允许没有版本的障碍物，true的话允许，false不允许，false在checkout的时候如果有障碍物就会停止检出，所以一般是true
     * 返回值：long 当前版本号
     * @throws SVNException
     */
    private static void doCheckout() throws SVNException{
        long nowRevision = svnClientManager.getUpdateClient().doCheckout(
                SVNURL.parseURIEncoded("svn://123.206.176.29/v12/发布包/weishier-timer-core")
                , new File("E:\\编程\\WEB容器\\apache-tomcat-8.0.47\\webapps\\weishier-timer-core")
                , SVNRevision.HEAD,SVNRevision.HEAD,SVNDepth.INFINITY,true);
        System.out.println("执行checkout操作成功，当前检出的版本号是：" + nowRevision);
    }

    /**
     * 创建目录-mkdir
     * @throws SVNException
     */
    private static void doMkDir() throws SVNException{
        String commitMessage = "创建一个目录";
        SVNCommitInfo svnCommitInfo = svnClientManager.getCommitClient().doMkDir(new SVNURL[]{SVNURL.parseURIEncoded("https://wlyfree-PC:8443/svn/testRepository/trunk/aaa"),SVNURL.parseURIEncoded("https://wlyfree-PC:8443/svn/testRepository/trunk/bbb")},commitMessage);
        System.out.println("执行mkdir操作成功，操作结果：" + gson.toJson(svnCommitInfo));
    }

    /**
     * 提交-commit
     * commit更改一个文件时，如果文件本身存在，则需要提交其父目录
     * @throws SVNException
     */
    private static void doCommit() throws SVNException{
        File[] files = new File[]{new File("E:\\svnWorkspace\\projectWorkingCopy"),new File("E:\\svnWorkspace\\projectWorkingCopy\\ccc")};
        //没有版本号的先执行add操作
        for(File tempFile : files){
            SVNStatus status = svnClientManager.getStatusClient().doStatus(tempFile,true);
            System.err.println(status);
            if(status == null || status.getContentsStatus() == SVNStatusType.STATUS_UNVERSIONED) {
                System.out.println("文件" + tempFile.getName() + "无版本号");
                svnClientManager.getWCClient().doAdd(tempFile, false, false, false, SVNDepth.INFINITY, false, false);
            }
        }
        //执行commit操作
        svnClientManager.getCommitClient().setIgnoreExternals(false);
        SVNProperties svnProperties = new SVNProperties();
        String[] changeLists = new String[]{};
        SVNCommitInfo svnCommitInfo = svnClientManager.getCommitClient().doCommit(files,false,"提交操作",svnProperties,changeLists,false,false,SVNDepth.fromRecurse(true));
        System.out.println("执行commit操作成功，操作结果：" + gson.toJson(svnCommitInfo));
    }

    /**
     * 更新-update
     * @throws SVNException
     */
    private static void doUpdate(String filePath) throws SVNException{
//        long nowRevision = svnClientManager.getUpdateClient().doUpdate(
//                new File("D:\\2")
//                ,SVNRevision.HEAD, SVNDepth.INFINITY,true,false);
        SVNRevision svnRevision = SVNRevision.create(2448);
        long nowRevision = svnClientManager.getUpdateClient().doUpdate(
                new File(filePath)
                ,svnRevision, SVNDepth.INFINITY,true,false);
        System.out.println("执行update操作成功，当前版本号：" + nowRevision);
    }

    /**
     * 锁定-lock
     * @throws SVNException
     */
    private static void doLock() throws SVNException{
//        svnClientManager.getWCClient().doLock(new SVNURL[]{SVNURL.parseURIEncoded("https://wlyfree-PC:8443/svn/testRepository/trunk/bbb/aa.txt")},true,"给文件加锁");
        svnClientManager.getWCClient().doLock(new File[]{new File("E:\\svnWorkspace\\projectWorkingCopy\\bbb\\aa.txt")},true,"给文件加锁");
        System.out.println("给文件加锁成功");
    }

    /**
     * 删除-delete
     * @throws SVNException
     */
    private static void doDelete() throws SVNException{
        SVNCommitInfo svnCommitInfo = svnClientManager.getCommitClient().doDelete(new SVNURL[]{SVNURL.parseURIEncoded("https://wlyfree-PC:8443/svn/testRepository/trunk/bbb"),SVNURL.parseURIEncoded("https://wlyfree-PC:8443/svn/testRepository/trunk/b.txt")},"执行删除操作，删除一个目录bbb一个文件b.txt");
        System.out.println("执行delete操作成功，操作结果：" + gson.toJson(svnCommitInfo));
    }

    /**
     * 复制-copy
     * @throws SVNException
     */
    private static void doCopy() throws SVNException{
        SVNCopySource svnCopySource1 = new SVNCopySource(SVNRevision.HEAD,SVNRevision.HEAD,SVNURL.parseURIEncoded("https://wlyfree-PC:8443/svn/testRepository/trunk/aaa/aa.txt"));
        SVNCopySource svnCopySource2 = new SVNCopySource(SVNRevision.HEAD,SVNRevision.HEAD,SVNURL.parseURIEncoded("https://wlyfree-PC:8443/svn/testRepository/trunk/aaa/bb.txt"));
        svnClientManager.getCopyClient().doCopy(new SVNCopySource[]{svnCopySource1,svnCopySource2},new File("E:\\svnWorkspace\\projectWorkingCopy\\bbb"),false,false,true);
        System.out.println("执行copy操作成功");
    }

    /**
     * 状态-status
     * @throws SVNException
     */
    private static void doStatus() throws SVNException{
        SVNStatus svnStatus = svnClientManager.getStatusClient().doStatus(new File("E:\\svnWorkspace\\projectWorkingCopy\\a.txt"),true);
        System.out.println("执行status操作成功，操作结果：" + gson.toJson(svnStatus));
    }

    /**
     * 信息-info
     * @throws SVNException
     */
    private static void doInfo(String repositoryPath) throws SVNException{
//        SVNInfo svnInfo = svnClientManager.getWCClient().doInfo(
//                new File("D:\\2\\weishier-common-core-1.0.0.jar"),SVNRevision.HEAD);
        SVNInfo svnInfo = svnClientManager.getWCClient().doInfo(
                new File(repositoryPath), SVNRevision.create(-1));
        System.out.println("执行info操作成功，操作结果：" + gson.toJson(svnInfo));
    }
}
